import * as THREE from "three";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";

export default class ThreeJs {
  scene: THREE.Scene | null = null;
  camera: THREE.PerspectiveCamera | null = null;
  renderer: THREE.WebGLRenderer | null = null;
  ambientLight: THREE.AmbientLight | null = null;
  mesh: THREE.Mesh | null = null;

  constructor() {
    this.init();
  }

  init(): void {
    // 第一步新建一个场景
    this.scene = new THREE.Scene();
    this.setCamera();
    this.setRenderer();
    this.setBox();
    this.setCone();
    this.setCircle();
    this.setCylinder();
    this.setDodecahedron();
    this.setOctahedron();
    this.setSphere();
    this.setTorus();
    // this.setShape();
    this.setText();
    this.setRing();
    this.render();
    // this.animate();
  }

  // 新建透视相机
  setCamera(): void {
    // 第二参数就是 长度和宽度比 默认采用浏览器  返回以像素为单位的窗口的内部宽度和高度
    this.camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    this.camera.position.z = 10;
  }

  // 设置渲染器
  setRenderer(): void {
    this.renderer = new THREE.WebGLRenderer();
    // 设置画布的大小
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    //这里 其实就是canvas 画布  renderer.domElement
    document.body.appendChild(this.renderer.domElement);
  }

  // 设置环境光
  setLight(): void {
    if (this.scene) {
      this.ambientLight = new THREE.AmbientLight(0xffffff); // 环境光
      this.scene.add(this.ambientLight);
    }
  }

  // 圆形几何体
  setCircle(): void {
    if (this.scene) {
      const geometry = new THREE.CircleGeometry(1.1, 32);
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const circle = new THREE.Mesh(geometry, material);
      circle.position.set(-6, 0, 0);
      this.scene.add(circle);
    }
  }

  // 创建圆锥几何体
  setCone(): void {
    if (this.scene) {
      const geometry = new THREE.ConeGeometry(1, 1, 8);
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const cone = new THREE.Mesh(geometry, material);
      cone.position.set(-3, 0, 0);
      this.scene.add(cone); //网格模型添加到场景中
    }
  }

  // 创建网格模型
  setBox(): void {
    if (this.scene) {
      const geometry = new THREE.BoxGeometry(1, 1.2, 1.3); //创建一个立方体几何对象Geometry
      const material = new THREE.MeshBasicMaterial({ color: 0xff3200 }); //材质对象Material
      // const texture = new THREE.TextureLoader().load(
      //   "/assets/imgs/UV_Grid_Sm.jpg"
      // ); //首先，获取到纹理
      // const material = new THREE.MeshBasicMaterial({ map: texture }); //然后创建一个phong材质来处理着色，并传递给纹理映射
      const box = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      box.position.set(0, 0, 0);
      this.scene.add(box); //网格模型添加到场景中
    }
  }

  // 圆柱几何体
  setCylinder(): void {
    if (this.scene) {
      const geometry = new THREE.CylinderGeometry(1, 1, 1, 8);
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const cylinder = new THREE.Mesh(geometry, material);
      cylinder.position.set(3, 0, 0);
      this.scene.add(cylinder); //网格模型添加到场景中
    }
  }

  // 十二面几何体
  setDodecahedron(): void {
    if (this.scene) {
      const geometry = new THREE.DodecahedronGeometry();
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const dodecahedron = new THREE.Mesh(geometry, material);
      dodecahedron.position.set(6, 0, 0);
      this.scene.add(dodecahedron); //网格模型添加到场景中
    }
  }

  // 八面几何体
  setOctahedron(): void {
    if (this.scene) {
      const geometry = new THREE.OctahedronGeometry();
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const octahedron = new THREE.Mesh(geometry, material);
      octahedron.position.set(0, 3, 0);
      this.scene.add(octahedron); //网格模型添加到场景中
    }
  }

  // 球几何体
  setSphere(): void {
    if (this.scene) {
      const geometry = new THREE.SphereGeometry(1, 32, 32);
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const sphere = new THREE.Mesh(geometry, material);
      sphere.position.set(-3, 3, 0);
      this.scene.add(sphere);
    }
  }

  // 圆环几何体
  setTorus(): void {
    if (this.scene) {
      const geometry = new THREE.TorusGeometry(0.8, 0.2, 16, 100);
      const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      const torus = new THREE.Mesh(geometry, material);
      torus.position.set(-6, 3, 0);
      this.scene.add(torus);
    }
  }

  // 圆环几何体
  setShape(): void {
    if (this.scene) {
      const x = 0,
        y = 0;

      const heartShape = new THREE.Shape();

      heartShape.moveTo(x + 5, y + 5);
      heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y);
      heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7);
      heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19);
      heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7);
      heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y);
      heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5);

      const geometry = new THREE.ShapeGeometry(heartShape);
      const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
      const shape = new THREE.Mesh(geometry, material);
      shape.position.set(3, 3, 0);
      this.scene.add(shape);
    }
  }

  // 圆环几何体
  setRing(): void {
    if (this.scene) {
      const geometry = new THREE.RingGeometry(0.5, 1, 16);
      const material = new THREE.MeshBasicMaterial({
        color: 0xffff00,
        side: THREE.DoubleSide,
      });
      const ring = new THREE.Mesh(geometry, material);
      ring.position.set(6, 3, 0);
      this.scene.add(ring);
    }
  }

  // 文本
  setText(): void {
    const loader = new FontLoader();
    loader.load("/assets/fonts/helvetiker_regular.typeface.json", (font) => {
      if (this.scene) {
        const geometry = new TextGeometry("text", {
          font: font,
          size: 0.8,
          height: 0.1,
          curveSegments: 12,
          bevelEnabled: true,
          bevelThickness: 0.1,
          bevelSize: 0.05,
          bevelSegments: 3,
        });
        geometry.center();
        const material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
        const text = new THREE.Mesh(geometry, material);
        text.position.set(3, 3, 0);
        console.log(this.scene, text);
        this.scene.add(text);
      }
    });
    // new FontLoader().load("/assets/fonts/helvetiker_regular.typeface.json", (font) => {
    //   if (this.scene) {
    //     const txtGeo = new TextGeometry("hello world", {
    //       font: font,
    //       // size: 0.8,
    //       // height: 0.1,
    //       // curveSegments: 12,
    //       // bevelEnabled: true,
    //       // bevelThickness: 0.1,
    //       // bevelSize: 0.05,
    //       // bevelSegments: 3,
    //     });
    //     const txtMater = new THREE.MeshBasicMaterial({ color: 0x0000ff });
    //     const txtMesh = new THREE.Mesh(txtGeo, txtMater);
    //     txtMesh.position.set(-2, 2, -0.4);
    //     this.scene.add(txtMesh);
    //   }
    // });
  }

  // 渲染
  render(): void {
    if (this.renderer && this.scene && this.camera) {
      this.renderer.render(this.scene, this.camera);
    }
  }

  // 动画
  animate(): void {
    requestAnimationFrame(this.animate.bind(this));
    // if (this.mesh) {
    //   this.mesh.rotation.x += 0.01;
    //   this.mesh.rotation.y += 0.01;
    // }
    this.render();
  }
}
